﻿//-----------------------------------------------------------------------
// <copyright file="WebSecurity.cs" company="deixei.com">
//     Copyright (c) deixei.com. All rights reserved.
// </copyright>
// <author>Marcio Parente</author>
//---------------------------------------------------------------------
namespace Deixei.Web
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Routing;
    using System.Web.Security;
    using Deixei.Domain;
    using Deixei;
    
    using Deixei.Infrastructure;

    public sealed class WebSecurity
    {
        public static HttpContextBase Context
        {
            get
            {
                return new HttpContextWrapper(HttpContext.Current);
            }
        }

        public static HttpRequestBase Request
        {
            get
            {
                return Context.Request;
            }
        }

        public static HttpResponseBase Response
        {
            get
            {
                return Context.Response;
            }
        }

        public static System.Security.Principal.IPrincipal User
        {
            get
            {
                return Context.User;
            }
        }

        public static string Username
        {
            get
            {
                return User.Identity.Name;
            }
        }

        public static bool IsAuthenticated
        {
            get
            {
                return User.Identity.IsAuthenticated;
            }
        }

        public static MembershipCreateStatus Register(string Username, string Password, string Email, bool IsApproved, string FirstName, string LastName)
        {
            MembershipCreateStatus CreateStatus;
            Membership.CreateUser(Username, Password, Email, null, null, IsApproved, null, out CreateStatus);

            if (CreateStatus == MembershipCreateStatus.Success)
            {
                DataContext dataContext = DeixeiContainer.Locator.GetInstance<DataContext>();
                //using (DataContext Context = DeixeiContainer.Locator.GetInstance<DataContext>())
                {
                    User User = dataContext.Users.FirstOrDefault(Usr => Usr.Username == Username);
                    User.FirstName = FirstName;
                    User.LastName = LastName;
                    dataContext.SaveChanges();
                }

                if (IsApproved)
                {
                    FormsAuthentication.SetAuthCookie(Username, false);
                }
            }

            return CreateStatus;
        }

        public static bool Login(string Username, string Password, bool persistCookie = false)
        {
            if (Membership.ValidateUser(Username, Password))
            {
                FormsAuthentication.SetAuthCookie(Username, persistCookie);
                return true;
            }
            else
            {
                return false;
            }
        }

        public static void Logout()
        {
            FormsAuthentication.SignOut();
        }

        public static MembershipUser GetUser(string Username)
        {
            return Membership.GetUser(Username);
        }

        public static int GetUserId(string userName)
        {
            MembershipUser user = Membership.GetUser(userName);
            if (user == null)
            {
                return -1;
            }

            // REVIEW: This cast is breaking the abstraction for the membershipprovider, we basically assume that userids are ints
            return (int)user.ProviderUserKey;
        }

        public static bool ChangePassword(string OldPassword, string NewPassword)
        {
            MembershipUser CurrentUser = Membership.GetUser(User.Identity.Name);
            return CurrentUser.ChangePassword(OldPassword, NewPassword);
        }

        public static bool DeleteUser(string Username)
        {
            return Membership.DeleteUser(Username);
        }

        public static List<MembershipUser> FindUsersByEmail(string Email, int PageIndex, int PageSize)
        {
            int totalRecords;
            return Membership.FindUsersByEmail(Email, PageIndex, PageSize, out totalRecords).Cast<MembershipUser>().ToList();
        }

        public static List<MembershipUser> FindUsersByName(string Username, int PageIndex, int PageSize)
        {
            int totalRecords;
            return Membership.FindUsersByName(Username, PageIndex, PageSize, out totalRecords).Cast<MembershipUser>().ToList();
        }

        public static List<MembershipUser> GetAllUsers(int PageIndex, int PageSize)
        {
            int totalRecords;
            return Membership.GetAllUsers(PageIndex, PageSize, out totalRecords).Cast<MembershipUser>().ToList();
        }


        public static void CreateAccount(string username, string password, bool requireConfirmationToken)
        {
            if (password.IsEmpty())
            {
                throw new MembershipCreateUserException(MembershipCreateStatus.InvalidPassword);
            }

            string hashedPassword = Crypto.HashPassword(password);
            if (hashedPassword.Length > 128)
            {
                throw new MembershipCreateUserException(MembershipCreateStatus.InvalidPassword);
            }

            if (username.IsEmpty())
            {
                throw new MembershipCreateUserException(MembershipCreateStatus.InvalidUserName);
            }


            Membership.CreateUser(username, password);
        }

        public static void CreateUserAndAccount(string username, string password)
        {
            CreateAccount(username, password, false);
        }

        public static bool ChangePassword(string UserName, string OldPassword, string NewPassword)
        {
            MembershipUser CurrentUser = Membership.GetUser(UserName);
            return CurrentUser.ChangePassword(OldPassword, NewPassword);
        }

        public static void CreateAccount(string username, string password)
        {
            CreateAccount(username, password, false);
        }
    }
}
